/*
 * CAN_Communication.c
 *
 *  Created on: Oct 28, 2019
 *      Author: nxa07657
 */

#include "CAN_Communication.h"

#include "Config.h"    /* the configuration header file*/
#include "load.h"

/* buffer index for CAN RX */
uint32_t CAN_RX_BufferIndex = 0;

/* circle buffer for CAN message receive */
can_message_t CAN_RX_Message_Buffer[CAN_RX_Buffer_MAX];

/* used for FlexCAN TX/RX interrupt test */
can_message_t CAN_TxMsg;  /* for CAN TX  */
can_message_t *CAN_RxMsg;  /* for CAN RX  */

uint8_t CAN_BufferReceive_Flag = 0;  /* FlexCAN received CAN frame flag */

/* CAN 2.0 A/B Buffer configuration */
 can_buff_config_t CAN_buffConfig =
 {
  .enableFD = false,
  .enableBRS = false,
  .fdPadding = 0xCC,
  .idType = CAN_MSG_ID_STD,
  .isRemote = false
 };

/*FUNCTION**********************************************************************
 *
 * Function Name : CAN_TX_RX_Callback
 * Description   : The callback of CAN TX & RX interrupt ISR
 *                 receive the CAN message with next circle buffer
 *                 set the received flag to inform bootloader for data process
 *
 * Implements    : CAN_TX_RX_Callback_Activity
 *END**************************************************************************/
void CAN_TX_RX_Callback(uint32_t instance, can_event_t eventType, uint32_t objIdx, void *driverState)
{

	if(CAN_EVENT_RX_COMPLETE==eventType)
	{
		/* past current message buffer address to the CAN_RxMsg pointer */
		CAN_RxMsg = &CAN_RX_Message_Buffer[CAN_RX_BufferIndex++%CAN_RX_Buffer_MAX];

		/* use next circle buffer for the new CAN message receive */
		CAN_Receive(&can_pal1_instance,RX_MB,&CAN_RX_Message_Buffer[CAN_RX_BufferIndex%CAN_RX_Buffer_MAX]);

		/* set the receive flag */
		CAN_BufferReceive_Flag = 1;
	}

}

/*FUNCTION**********************************************************************
 *
 * Function Name : CAN_CommunicationInit
 * Description   : Send the CAN message with blocking method and set timeout = 100ms
 *
 * Implements    : CAN_CommunicationInit_Activity
 *END**************************************************************************/
status_t CAN_CommunicationInit(void)
{
	status_t ret = STATUS_SUCCESS;
	/*
	 * initialize the FlexCAN to work as a CAN 2.0 A/B note with 500Kbit/s
	 */
	ret = CAN_Init(&can_pal1_instance, &can_pal1_Config0);

	/* configure the transmit MB */
	ret = CAN_ConfigTxBuff(&can_pal1_instance,TX_MB, &CAN_buffConfig);

	/* configure the receive MB with downloadID for app download  */
	ret = CAN_ConfigRxBuff(&can_pal1_instance, RX_MB, &CAN_buffConfig, DownLoadID);

	/*install the TX/RX call back*/
	ret = CAN_InstallEventCallback(&can_pal1_instance,CAN_TX_RX_Callback, NULL);

	/*start the CAN message receive*/
	ret = CAN_Receive(&can_pal1_instance,RX_MB,&CAN_RX_Message_Buffer[CAN_RX_BufferIndex]);

	return ret;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : CAN_TransmitMsg
 * Description   : Send the CAN message with blocking method and set timeout = 100ms
 *
 * Implements    : CAN_TransmitMsg_Activity
 *END**************************************************************************/
status_t CAN_TransmitMsg(uint32_t mb_num, can_message_t * msg)
{
	status_t ret = STATUS_SUCCESS;
	/*
	 * send out the CAN message with blocking method and set timeout = 100ms
	 */
	ret = CAN_SendBlocking(&can_pal1_instance,mb_num,msg, 100);

	return ret;
}

/******************end of the file ***************/
